﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Lizk.SimpleHUD;
using System.Xml.Serialization;

namespace SharpMedia.Input
{
    [XmlRoot]
    public class KeyboardBinding<T>
    {
        /// <summary>
        /// Gets or sets the command.
        /// </summary>
        /// <value>The command.</value>
        public T Command { get; set; }
        
        /// <summary>
        /// Gets or sets the primary key.
        /// </summary>
        /// <value>The primary.</value>
        public Keys Primary { get; set; }

        /// <summary>
        /// Gets or sets the primary mods.
        /// </summary>
        /// <value>The primary mods.</value>
        public Keys PrimaryMods { get; set; }

        /// <summary>
        /// Gets or sets the secondary key.
        /// </summary>
        /// <value>The secondary.</value>
        public Keys Secondary { get; set; }


        /// <summary>
        /// Gets or sets the secondary mods.
        /// </summary>
        /// <value>The secondary mods.</value>
        public Keys SecondaryMods { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="KeyboardBinding"/> class.
        /// </summary>
        public KeyboardBinding()
        {
            Primary = Keys.None;
            Secondary = Keys.None;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="KeyboardBinding&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="command">The command.</param>
        public KeyboardBinding(T command) : this()
        {
            this.Command = command;

        }

        /// <summary>
        /// Assigns a new key to this binding.
        /// </summary>
        /// <param name="newKey">The new key.</param>
        public void AssignKey(Keys newKey, Keys mods)
        {
            if (Primary != Keys.None && Secondary == Keys.None)
            {
                if (newKey == Primary && mods == PrimaryMods)
                    return;
                Secondary = newKey;
                SecondaryMods = mods;
            }
            else
            {
                Primary = newKey;
                PrimaryMods = mods;
                Secondary = Keys.None;
                SecondaryMods = Keys.None;
            }
        }

        public override string ToString()
        {
            List<string> modifiers = new List<string>(3);

            if ((PrimaryMods & Keys.Control) == Keys.Control)
                modifiers.Add("Ctrl");
            if ((PrimaryMods & Keys.Alt) == Keys.Alt)
                modifiers.Add("Alt");
            if ((PrimaryMods & Keys.Shift) == Keys.Shift)
                modifiers.Add("Shift");

            string primary = modifiers.Count > 0 ? string.Join("+", modifiers.ToArray()) + "+" + this.Primary : this.Primary.ToString();
            
            modifiers.Clear();
            if ((SecondaryMods & Keys.Control) == Keys.Control)
                modifiers.Add("Ctrl");
            if ((SecondaryMods & Keys.Alt) == Keys.Alt)
                modifiers.Add("Alt");
            if ((SecondaryMods & Keys.Shift) == Keys.Shift)
                modifiers.Add("Shift");

            string secondary = modifiers.Count > 0 ? string.Join("+", modifiers.ToArray()) + "+" + this.Secondary : this.Secondary.ToString();


            return primary + " - " + secondary;
        }

        public string PrimaryString
        {
            get
            {
                List<string> modifiers = new List<string>(3);

                if ((PrimaryMods & Keys.Control) == Keys.Control)
                    modifiers.Add("Ctrl");
                if ((PrimaryMods & Keys.Alt) == Keys.Alt)
                    modifiers.Add("Alt");
                if ((PrimaryMods & Keys.Shift) == Keys.Shift)
                    modifiers.Add("Shift");

                return modifiers.Count > 0 ? string.Join("+", modifiers.ToArray()) + "+" + this.Primary : this.Primary.ToString();

            }
        }

        public string SecondaryString
        {
            get
            {
                List<string> modifiers = new List<string>(3);

                if ((SecondaryMods & Keys.Control) == Keys.Control)
                    modifiers.Add("Ctrl");
                if ((SecondaryMods & Keys.Alt) == Keys.Alt)
                    modifiers.Add("Alt");
                if ((SecondaryMods & Keys.Shift) == Keys.Shift)
                    modifiers.Add("Shift");

                return modifiers.Count > 0 ? string.Join("+", modifiers.ToArray()) + "+" + this.Secondary : this.Secondary.ToString();


            }
        }

    }
}
